package com.lvmama.search.spider.proxy;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class ProxyManager {
	private static Log log = LogFactory.getLog(ProxyManager.class);
	private static IProxyProvider proxyProvider = new XiCiProxyProvider();
	private static ExecutorService es = Executors.newFixedThreadPool(10);
	public static volatile List<ProxyIp> proxyList=new ArrayList<ProxyIp>();
	static {
		Executors.newSingleThreadScheduledExecutor().
				scheduleAtFixedRate(new Runnable() {
					public void run() {
						try {
							List<ProxyIp> temp=getProxyList();
							if(temp!=null&&!temp.isEmpty()) {
								log.info("reset proxy list size :"+temp.size());
								proxyList=proxyList;
							}
						} catch (Exception e) {
							log.error("exeception",e);
						}
					}
				}, 10l, 10l, TimeUnit.MINUTES);
	}
	public static void init(){
		proxyList=getProxyList();
	} 
	public static List<ProxyIp> getProxyList() {
		List<ProxyIp> allProxyList = proxyProvider.getProxyIpList();
		if (allProxyList == null || allProxyList.isEmpty())
			return new ArrayList<ProxyIp>();
		List<ProxyIp> validatProxyList = new ArrayList<ProxyIp>();
		List<Future<ProxyIp>> fList = new ArrayList<Future<ProxyIp>>(allProxyList.size());
		for (final ProxyIp proxyIp : allProxyList) {
			fList.add(es.submit(new Callable<ProxyIp>() {
				public ProxyIp call() throws Exception {
					proxyIp.setValidate(ProxyValidator.isProxyValidate(proxyIp));
					return proxyIp;
				}
			}));
		}
		for (Future<ProxyIp> future : fList) {
			try {
				ProxyIp proxyIp = future.get(10, TimeUnit.SECONDS);
				if (proxyIp.isValidate()) {
					validatProxyList.add(proxyIp);
					log.info(proxyIp + ",is valudate");
				} else {
					log.info(proxyIp + ",is not valudate");
				}
			} catch (Throwable e) {
				log.error("error to geto future", e);
			}
		}
		return validatProxyList;
	}

	public static ProxyIp getProxyIp() {
		if(proxyList!=null&&!proxyList.isEmpty()) {
			int count=1;
			while (count<10) {
				count++;
				try {
					return proxyList.get(new Random().nextInt(proxyList.size()));
				} catch (Exception e) {
					log.error("get proxy ip error",e);
				}
			}
		}
		return null;
	}
}
